/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bea.file;

import bea.main.Main;
import bea.ui.BananaPanel;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;

/**
 *
 * @author user1
 */
public class FileProcessor {
    
    //header
    public static String filename, ext;
    public static int namelength, extlength;
    public static byte checksum;
    public static long size;
    
    public static File inFile, outFile;
    public static JFileChooser inChooser, outChooser;
    
    public static byte[] input, output;
    
    public static void init() {
        inChooser = new JFileChooser("Input File");
        outChooser = new JFileChooser("Output File");
        ext = "";
        extlength = 0;
        filename = "";
        namelength = 0;
        size = 0;
        checksum = 0;
    }
    
    public static byte countChecksum(byte[] bytes, long length) {
        int sum = 0;
        for (int i = 0; i < length; i++) {
            sum += bytes[i];
            sum %= 256;
        }
        return (byte) sum;
    }
    
    public static void write(byte[] from) {
        size = from.length;
        checksum = countChecksum(from,from.length);

        //get name
        ext = inFile.getName();
        int dot = ext.indexOf(".");

        //filename
        filename = ext.substring(0,dot);
        namelength = filename.length();

        //ext
        ext = ext.substring(dot+1, ext.length());
        extlength = ext.length();

        int bytesize = 1+8+4+namelength+4+extlength+from.length;
        input = new byte[bytesize]; //checksum + size + namelength + name + extlength + ext + isi
        
        ByteBuffer buf = ByteBuffer.wrap(input);
        buf.put(checksum);
        buf.putLong(size);
        buf.putInt(namelength);
        buf.put(filename.getBytes());
        buf.putInt(extlength);
        buf.put(ext.getBytes());
        buf.put(from);
        
    }
    
    public static boolean read(byte[] from) throws OutOfMemoryError {
        
        byte[] temp;
        ByteBuffer buf = ByteBuffer.wrap(from);
       
        //checksum
        checksum = buf.get();
        
        //ukuran 
        size = buf.getLong();
        
        //panjang nama file
        namelength = buf.getInt();
        //nama file
        temp = new byte[namelength];
        buf.get(temp, 0, namelength);
        filename = new String(temp);
        
        //panjang ekstensi
        extlength = buf.getInt();
        
        //ekstensi
        temp = new byte[extlength];
        buf.get(temp, 0, extlength);
        ext = new String(temp);
        
        temp = new byte[(int)size];
        buf.get(temp,0,(int)size);
        
        
        //DEBUG
//        
//        System.out.println("filename = " + filename);
//        System.out.println("filelength = " + namelength);
//        System.out.println("ext = " + ext);
//        System.out.println("extlength = " + extlength);
//         
        boolean ceksum = (checksum == (countChecksum(temp,size))); 
        
        if (ceksum) {
            output = new byte[(int)size];
            System.arraycopy(temp, 0, output, 0, (int) size);
        }
        else output = null;
        return ceksum;
    }
    
    public static void load() {
        int respon = inChooser.showOpenDialog(Main.panel.frame);
        if (respon == JFileChooser.APPROVE_OPTION) {
            inFile = inChooser.getSelectedFile();
            Main.panel.in.setText(inChooser.getSelectedFile().getName());
            
            //load file
            try {
                InputStream is = new FileInputStream(inFile);
                byte[] temp;
                long len = inFile.length();
                if (len > Integer.MAX_VALUE){
                    JOptionPane.showMessageDialog(Main.panel.frame, "Please choose smaller file");
                }else{
                    input = new byte[(int)len];
                    is.read(input, 0, input.length);
                    is.close();
                    Main.panel.setText(new String(input));
                    JOptionPane.showMessageDialog(Main.panel.frame, "Success! File size : " + input.length + " Bytes");
                }
            } catch (IOException ioe) {
                
            }
        }
    }
    
    public static void prepare() {
        byte[] temp = new byte[input.length];
        System.arraycopy(input, 0, temp, 0, input.length);
        write(temp);
    }
    
    public static void confirm(byte[] decipher) throws Exception {
        boolean trueKey = read(decipher);
        if (!trueKey)
            JOptionPane.showMessageDialog(Main.panel.frame, "You got the wrong banana bro!");
        else {
            //Ubah UI
            Main.panel.setText(new String(output));
        }
    }
    
    public static void save() {
         outChooser.setFileFilter(new FileFilter() {
            
            @Override
            public boolean accept(File f) {
                if (f.isDirectory()) {
                    return true;
                }               
                String s = f.getName();
                return s.endsWith("." + ext)||s.endsWith("." + ext.toUpperCase())||s.endsWith(".potato");
            }

            @Override
            public String getDescription() {
                return (Main.panel.state == BananaPanel.STATE_EN) ? "Encrypted File (potato)" :"Decrypted File (" + ext + ")";
            }        
        });
        
        File guessFile;
        if (Main.panel.state == BananaPanel.STATE_DE) {
            guessFile = new File(filename);
            outChooser.setSelectedFile(guessFile);
        }
        int retVal = outChooser.showSaveDialog(Main.panel.frame);
        
        if (retVal == JFileChooser.APPROVE_OPTION) {
            try {
                String path = (Main.panel.state == BananaPanel.STATE_DE)?
                    (outChooser.getSelectedFile().getAbsolutePath().endsWith("." + ext))? outChooser.getSelectedFile().getAbsolutePath() : outChooser.getSelectedFile().getAbsolutePath() + "." + ext:
                    (outChooser.getSelectedFile().getAbsolutePath().endsWith(".potato"))? outChooser.getSelectedFile().getAbsolutePath() : outChooser.getSelectedFile().getAbsolutePath() + ".potato";
                outFile = new File(path);
                FileOutputStream wri = new FileOutputStream(path);
                if (output != null) {
                    wri.write(output);
                    
                }
                wri.close();
                if (outFile != null)
                    JOptionPane.showMessageDialog(Main.panel.frame, "Success! File name : " + outFile.getName());
            } catch (IOException ioex) {
                JOptionPane.showMessageDialog(Main.panel.frame, "Error saving file");
            }
        }
    }
}
